package org.jdcenter.rmi.impl;

import java.io.*;
import java.util.*;

import static org.jdcenter.rmi.impl.Glossary.*;

import org.jdcenter.rmi.abs.*;

public class RMIFactory {
    private static class SchemeImpl implements Scheme {
        private Properties properties;

        public SchemeImpl(String file) throws IOException {
        	String filePath = System.getProperty("jdstream.conf.url")+file;
        	File f = new File(filePath);
        	BufferedInputStream fileIn = null;
        	if(f.exists()){
        		fileIn = new BufferedInputStream(new FileInputStream(f));
        	}else{
        		fileIn = new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(file));
        	}
            this.properties = new Properties();
            this.properties.load(fileIn);

            this.verify(HANDLER_CACHE_INITIAL_SIZE);
            this.verify(HANDLER_CACHE_INCREASE_STEP);
            this.verify(HANDLER_COOKIE_RESERVED_TIME);
            this.verify(CLIENT_HANDLER_THREAD_COUNT);
            this.verify(CHANNEL_TICKER_PERIODS);
            this.verify(CHANNEL_TICKER_INITIAL_DELAY);
            this.verify(LOCAL_CHANNEL_RESERVED_AFTER_FREE);
            this.verify(SERVER_CALLBACK_THREAD_COUNT);
        }

        public int getProperty(String name) {
            return Integer.parseInt(this.properties.getProperty(name));
        }

        private void verify(String name) throws IOException {
            try {
                String value = (String) this.properties.get(name);
                if(value == null || value.trim().length() == 0)
                    throw new InvalidPropertiesFormatException(
                            String.format("Property[%s]: missing", name));
                if(Integer.parseInt(value) < 1)
                    throw new InvalidPropertiesFormatException(
                            String.format("Property[%s]: illegal value", name));
            } catch (Exception e) {
                throw new InvalidPropertiesFormatException(
                        String.format("Property[%s]: %s", name, e.toString()));
            }
        }
    }

    private static ChannelFactory client;
    private static ServerFactory server;

    public static synchronized ChannelFactory getChannelFactory(String file) throws IOException {
        if(client == null)
            client = new LocalChannelFactory(new SchemeImpl(file));
        return client;
    }

    public static synchronized ServerFactory getServerFactory(String file) throws IOException {
        if(server == null)
            server = new LocalServerFactory(new SchemeImpl(file));
        return server;
    }
}

